/*
 * SwingUtilitiesDelegate.h  0.4.0 / Nov 17, 2010
 *
 * Copyright (c) 2010 - 2011, cute4j.com and contributors.
 *
 * This software is licensed under the LGPL version 2.1 license.
 * A copy of this license is included in the file LICENSE-LGPL.txt.
 */
#ifndef SWINGUTILITIESDELEGATE_H
#define SWINGUTILITIESDELEGATE_H

#include "Cute4jCore.h"

// SwingUtilitiesDelegate Class. -----------------------------------------------

/*!
 * \brief SwingUtilities Delegate.
 *
 * \author Slobodan Vrkacevic
 * \version 0.4.0
 */
class CUTE4J_EXPORT SwingUtilitiesDelegate : public QObject
{
  Q_OBJECT
private:
  SwingUtilitiesDelegate();
  SwingUtilitiesDelegate(const SwingUtilitiesDelegate &);
  ~SwingUtilitiesDelegate();
public: // native calls
  static void invokeLater(JNIEnv *env, jclass cls, jobject target);
  static void invokeAndWait(JNIEnv *env, jclass cls, jobject target);
  static void invokeSafeAndWait(JNIEnv *env, jclass cls, jobject safeTarget);
public: // helper methods
  static void initialize(JNIEnv *env, jclass runnableClass, jclass iteClass);
  static jint invokeIntAndWait(JNIEnv *env, jobject obj, jmethodID mid, ...);
  static jlong invokeLongAndWait(JNIEnv *env, jobject obj, jmethodID mid, ...);
private:
  struct TargetFrame {
    jobject target;
    jthrowable exception;
  };
  struct MethodFrame {
    jobject obj;
    jmethodID mid;
    va_list args;
  };
  struct IntMethodFrame : MethodFrame {
    jint result;
  };
  struct LongMethodFrame : MethodFrame {
    jlong result;
  };
private:
  void invokeLater(jobject target);
  void invokeAndWait(TargetFrame *targetFrame);
  void invokeSafeAndWait(jobject safeTarget);
  void invokeIntAndWait(IntMethodFrame *methodFrame);
  void invokeLongAndWait(LongMethodFrame *methodFrame);
private slots:
  void invokeLaterSlot(jobject target);
  void invokeAndWaitSlot(TargetFrame *targetFrame);
  void invokeIntAndWaitSlot(IntMethodFrame *methodFrame);
  void invokeLongAndWaitSlot(LongMethodFrame *methodFrame);
signals:
  void invokeLaterSignal(jobject target);
  void invokeAndWaitSignal(TargetFrame *targetFrame);
  void invokeSafeAndWaitSignal(jobject safeTarget);
  void invokeIntAndWaitSignal(IntMethodFrame *methodFrame);
  void invokeLongAndWaitSignal(LongMethodFrame *methodFrame);
private:
  static jmethodID sm_runMID;
  static jmethodID sm_iteConstructorMID;
  static SwingUtilitiesDelegate *swingUtilitiesDelegate;
};

#endif // SWINGUTILITIESDELEGATE_H
